


package wiiusej.connection;

import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import wiiusej.Wiimote;
import wiiusej.wiiusejevents.GenericEvent;
import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent;




public class ShareConnectionCell {

	//Logger
	private static Logger fileLogger;
	
	private static HashMap<Integer, BlockingQueue<GenericEvent>> wiimoteComChannels;
	
	//Explicit Log and Condition Variable
	private static Lock eventLock = new ReentrantLock();
    private static Condition eventCondVar = eventLock.newCondition();

    
    private Lock wiimoteLock = new ReentrantLock();
    private Condition notReadWiimote = eventLock.newCondition();
    private Condition notUploadedWiimote = eventLock.newCondition();
    
    
    //Write-Read Lock System
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    
    //Locks for wiimotes structure
    private final Lock wiimotesR = lock.readLock();
    private final Lock wiimotesW = lock.writeLock();
    
    //Locks for event structure
    
    private HashMap<Integer, Wiimote> wiimotes;
	private boolean changeWiimoteState = false;
	
	
	private WiiUseApiEvent event;
	private boolean changeEventState;
	
	
	public ShareConnectionCell(){
			
		//Init the wiimotes which have been connected
		this.wiimotes = null;
		
		//Event data and control structures
		event = null;
		changeEventState = false;	
		
		//Logger init
		PropertyConfigurator.configure("log4j.properties");
		fileLogger = Logger.getLogger("sharedCell");			
	}
	
	
	
	
	/** WIIMOTE OPERATIONS
	*/	
	public HashMap<Integer, BlockingQueue<GenericEvent>>  getAllWiimotes(String who){
		
		wiimotesR.lock();		
		try{
			fileLogger.info("Consumer Operation: getAllWiimotes. Got: " + wiimotes + "Thread: " + who);
			return wiimoteComChannels;			
		}finally{
			wiimotesR.unlock();
		}
	}
	
	public HashMap<Integer, BlockingQueue<GenericEvent>> uploadWiimotes(HashMap<Integer, BlockingQueue<GenericEvent>> queue, 
			String who){
		
		wiimotesW.lock();
		
		try{
			fileLogger.info("Producer Operation: uploadWiimotes. Entered: " + wiimotes + "Thread: " + who);
			return this.wiimoteComChannels = queue;			
		}finally{
			wiimotesW.unlock();
		}
	}	
	
}
